package cn.yemuysy.code.lingting.util;

import cn.yemuysy.code.lingting.model.PinyinGraph;
import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.HanyuPinyinVCharType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;

import java.util.ArrayList;
import java.util.List;

/**
 * 拼音转换工具类
 * 基于pinyin4j库，提供多音字处理和拼音图构建功能
 */
public class PinyinUtil {
    
    /**
     * 拼音输出格式配置
     */
    private static final HanyuPinyinOutputFormat OUTPUT_FORMAT;
    
    static {
        OUTPUT_FORMAT = new HanyuPinyinOutputFormat();
        OUTPUT_FORMAT.setCaseType(HanyuPinyinCaseType.LOWERCASE);  // 小写
        OUTPUT_FORMAT.setToneType(HanyuPinyinToneType.WITHOUT_TONE); // 无声调
        OUTPUT_FORMAT.setVCharType(HanyuPinyinVCharType.WITH_V); // ü用v表示
    }
    
    /**
     * 获取单个字符的所有可能拼音
     * @param character 输入字符
     * @return 拼音列表，非中文字符返回原字符
     */
    public static List<String> getPinyins(char character) {
        List<String> pinyins = new ArrayList<>();
        
        if (isChinese(character)) {
            try {
                String[] pinyinArray = PinyinHelper.toHanyuPinyinStringArray(character, OUTPUT_FORMAT);
                if (pinyinArray != null && pinyinArray.length > 0) {
                    for (String pinyin : pinyinArray) {
                        if (pinyin != null && !pinyin.trim().isEmpty()) {
                            pinyins.add(pinyin.trim().toLowerCase());
                        }
                    }
                }
            } catch (BadHanyuPinyinOutputFormatCombination e) {
                // 转换失败时，使用原字符
                pinyins.add(String.valueOf(character));
            }
        } else {
            // 非中文字符直接使用原字符
            pinyins.add(String.valueOf(character));
        }
        
        // 如果没有获取到拼音，使用原字符
        if (pinyins.isEmpty()) {
            pinyins.add(String.valueOf(character));
        }
        
        return pinyins;
    }
    
    /**
     * 获取字符串的第一个拼音组合
     * @param text 输入文本
     * @return 拼音字符串（空格分隔）
     */
    public static String getFirstPinyin(String text) {
        if (text == null || text.isEmpty()) {
            return "";
        }
        
        StringBuilder pinyinBuilder = new StringBuilder();
        for (int i = 0; i < text.length(); i++) {
            char character = text.charAt(i);
            List<String> pinyins = getPinyins(character);
            if (!pinyins.isEmpty()) {
                pinyinBuilder.append(pinyins.get(0));
            }
            if (i < text.length() - 1) {
                pinyinBuilder.append(" ");
            }
        }
        
        return pinyinBuilder.toString();
    }
    
    /**
     * 构建文本的拼音图
     * @param text 输入文本
     * @return 拼音图对象
     */
    public static PinyinGraph buildPinyinGraph(String text) {
        if (text == null || text.isEmpty()) {
            return new PinyinGraph("");
        }
        
        PinyinGraph graph = new PinyinGraph(text);
        
        for (int i = 0; i < text.length(); i++) {
            char character = text.charAt(i);
            PinyinGraph.PinyinNode node = new PinyinGraph.PinyinNode(character, i);
            
            List<String> pinyins = getPinyins(character);
            for (String pinyin : pinyins) {
                node.addPinyin(pinyin);
            }
            
            graph.addNode(node);
        }
        
        return graph;
    }
    
    /**
     * 检查字符是否为中文
     * @param character 输入字符
     * @return true如果是中文字符
     */
    public static boolean isChinese(char character) {
        Character.UnicodeBlock unicodeBlock = Character.UnicodeBlock.of(character);
        return unicodeBlock == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS
                || unicodeBlock == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A
                || unicodeBlock == Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_B
                || unicodeBlock == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS
                || unicodeBlock == Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS_SUPPLEMENT;
    }
    
    /**
     * 计算文本中中文字符的数量
     * @param text 输入文本
     * @return 中文字符数量
     */
    public static int getChineseCharCount(String text) {
        if (text == null) {
            return 0;
        }
        
        int count = 0;
        for (char character : text.toCharArray()) {
            if (isChinese(character)) {
                count++;
            }
        }
        return count;
    }
    
    /**
     * 检查文本是否包含多音字
     * @param text 输入文本
     * @return true如果包含多音字
     */
    public static boolean hasMultiPronunciation(String text) {
        if (text == null || text.isEmpty()) {
            return false;
        }
        
        for (char character : text.toCharArray()) {
            if (isChinese(character)) {
                List<String> pinyins = getPinyins(character);
                if (pinyins.size() > 1) {
                    return true;
                }
            }
        }
        return false;
    }
    
    /**
     * 获取文本中多音字的数量
     * @param text 输入文本
     * @return 多音字数量
     */
    public static int getMultiPronunciationCount(String text) {
        if (text == null || text.isEmpty()) {
            return 0;
        }
        
        int count = 0;
        for (char character : text.toCharArray()) {
            if (isChinese(character)) {
                List<String> pinyins = getPinyins(character);
                if (pinyins.size() > 1) {
                    count++;
                }
            }
        }
        return count;
    }
    
    /**
     * 将拼音字符串转换为音节数组
     * @param pinyinString 拼音字符串（空格或其他分隔符分隔）
     * @return 音节数组
     */
    public static String[] parsePinyinString(String pinyinString) {
        if (pinyinString == null || pinyinString.trim().isEmpty()) {
            return new String[0];
        }
        
        // 支持多种分隔符
        return pinyinString.trim().split("\\s+|[,，.。;；]");
    }
    
    /**
     * 规范化拼音字符串（去除声调，统一格式）
     * @param pinyin 输入拼音
     * @return 规范化后的拼音
     */
    public static String normalizePinyin(String pinyin) {
        if (pinyin == null) {
            return "";
        }
        
        // 移除数字（声调）
        String normalized = pinyin.replaceAll("[0-9]", "");
        
        // 转换为小写
        normalized = normalized.toLowerCase();
        
        // 处理特殊字符
        normalized = normalized.replace("ü", "v");
        
        return normalized.trim();
    }
    
    /**
     * 批量规范化拼音数组
     * @param pinyins 拼音数组
     * @return 规范化后的拼音数组
     */
    public static String[] normalizePinyins(String[] pinyins) {
        if (pinyins == null) {
            return new String[0];
        }
        
        String[] normalized = new String[pinyins.length];
        for (int i = 0; i < pinyins.length; i++) {
            normalized[i] = normalizePinyin(pinyins[i]);
        }
        return normalized;
    }
} 